home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / MAME / src / machine / sega.c < prev    next >
C/C++ Source or Header  |  2000-04-23  |  4KB  |  180 lines

  1. /***************************************************************************
  2.  
  3.   machine.c
  4.  
  5.   Functions to emulate general aspects of the machine (RAM, ROM, interrupts,
  6.   I/O ports)
  7.  
  8. ***************************************************************************/
  9.  
  10. /*
  11.  * History:
  12.  *
  13.  * 980206 Cleaned up and simplified the spinner routines. BW
  14.  *
  15.  */
  16.  
  17. #include "driver.h"
  18.  
  19. extern void (*sega_decrypt)(int,unsigned int *);
  20. unsigned char *sega_mem;
  21.  
  22. unsigned char mult1;
  23. unsigned short result;
  24. unsigned char ioSwitch; /* determines whether we're reading the spinner or the buttons */
  25.  
  26. WRITE_HANDLER( sega_w )
  27. {
  28.     int pc,off;
  29.  
  30.     pc = cpu_getpreviouspc();
  31.     off = offset;
  32.  
  33.     /* Check if this is a valid PC (ie not a spurious stack write) */
  34.     if (pc != -1)
  35.     {
  36.         int op, page;
  37.         unsigned int bad;
  38.  
  39.         op = sega_mem[pc] & 0xFF;
  40.         if (op == 0x32)
  41.         {
  42.             bad = sega_mem[pc+1] & 0xFF;
  43.             page = (sega_mem[pc+2] & 0xFF) << 8;
  44.             (*sega_decrypt)(pc,&bad);
  45.             off = (page & 0xFF00) | (bad & 0x00FF);
  46.         }
  47.     }
  48.  
  49.  
  50.     /* MWA_ROM */
  51.     if      ((off>=0x0000) && (off<=0xbfff))
  52.     {
  53.         ;
  54.     }
  55.     /* MWA_RAM */
  56.     else if ((off>=0xc800) && (off<=0xefff))
  57.     {
  58.         sega_mem[off]=data;
  59.     }
  60. }
  61.  
  62. int sega_interrupt (void)
  63. {
  64.     if (input_port_5_r(0) & 0x01)
  65.         return nmi_interrupt();
  66.     else
  67.         return interrupt();
  68. }
  69.  
  70. WRITE_HANDLER( sega_mult1_w )
  71. {
  72.     mult1 = data;
  73. }
  74.  
  75. WRITE_HANDLER( sega_mult2_w )
  76. {
  77.     /* Curiously, the multiply is _only_ calculated by writes to this port. */
  78.     result = mult1 * data;
  79. }
  80.  
  81. WRITE_HANDLER( sega_switch_w ) {
  82.  
  83.     ioSwitch = data;
  84. /*    logerror("ioSwitch: %02x\n",ioSwitch); */
  85.     }
  86.  
  87. READ_HANDLER( sega_mult_r )
  88. {
  89.     int c;
  90.  
  91.     c = result & 0xff;
  92.     result >>= 8;
  93.     return (c);
  94. }
  95.  
  96. /***************************************************************************
  97.  
  98.   The Sega games store the DIP switches in a very mangled format that's
  99.   not directly useable by MAME.  This function mangles the DIP switches
  100.   into a format that can be used.
  101.  
  102.   Original format:
  103.   Port 0 - 2-4, 2-8, 1-4, 1-8
  104.   Port 1 - 2-3, 2-7, 1-3, 1-7
  105.   Port 2 - 2-2, 2-6, 1-2, 1-6
  106.   Port 3 - 2-1, 2-5, 1-1, 1-5
  107.   MAME format:
  108.   Port 6 - 1-1, 1-2, 1-3, 1-4, 1-5, 1-6, 1-7, 1-8
  109.   Port 7 - 2-1, 2-2, 2-3, 2-4, 2-5, 2-6, 2-7, 2-8
  110. ***************************************************************************/
  111.  
  112. READ_HANDLER( sega_ports_r )
  113. {
  114.     int dip1, dip2;
  115.  
  116.     dip1 = input_port_6_r(offset);
  117.     dip2 = input_port_7_r(offset);
  118.  
  119.     switch(offset)
  120.     {
  121.         case 0:
  122.             return ((input_port_0_r(0) & 0xF0) | ((dip2 & 0x08)>>3) |
  123.                  ((dip2 & 0x80)>>6) | ((dip1 & 0x08)>>1) | ((dip1 & 0x80)>>4));
  124.         case 1:
  125.             return ((input_port_1_r(0) & 0xF0) | ((dip2 & 0x04)>>2) |
  126.                  ((dip2 & 0x40)>>5) | ((dip1 & 0x04)>>0) | ((dip1 & 0x40)>>3));
  127.         case 2:
  128.             return ((input_port_2_r(0) & 0xF0) | ((dip2 & 0x02)>>1) |
  129.                  ((dip2 & 0x20)>>4) | ((dip1 & 0x02)<<1) | ((dip1 & 0x20)>>2));
  130.         case 3:
  131.             return ((input_port_3_r(0) & 0xF0) | ((dip2 & 0x01)>>0) |
  132.                  ((dip2 & 0x10)>>3) | ((dip1 & 0x01)<<2) | ((dip1 & 0x10)>>1));
  133.     }
  134.  
  135.     return 0;
  136. }
  137.  
  138.  
  139. READ_HANDLER( sega_IN4_r ) {
  140.  
  141. /*
  142.  * The values returned are always increasing.  That is, regardless of whether
  143.  * you turn the spinner left or right, the self-test should always show the
  144.  * number as increasing. The direction is only reflected in the least
  145.  * significant bit.
  146.  */
  147.  
  148.     int delta;
  149.     static int sign;
  150.     static int spinner;
  151.  
  152.     if (ioSwitch & 1) /* ioSwitch = 0x01 or 0xff */
  153.         return readinputport (4);
  154.  
  155.     /* else ioSwitch = 0xfe */
  156.  
  157.     /* I'm sure this can be further simplified ;-) BW */
  158.     delta = readinputport(8);
  159.     if (delta != 0)
  160.     {
  161.         sign = delta >> 7;
  162.         if (sign)
  163.             delta = 0x80-delta;
  164.         spinner += delta;
  165.     }
  166.     return (~((spinner<<1) | sign));
  167. }
  168.  
  169. READ_HANDLER( elim4_IN4_r )
  170. {
  171.     /* If the ioPort ($f8) is 0x1f, we're reading the 4 coin inputs.    */
  172.     /* If the ioPort ($f8) is 0x1e, we're reading player 3 & 4 controls.*/
  173.  
  174.     if (ioSwitch == 0x1e)
  175.         return readinputport (4);
  176.     if (ioSwitch == 0x1f)
  177.         return readinputport (8);
  178.     return (0);
  179. }
  180.